// @Author : zaniu(zzaniu@126.com)
// @Time   : 2021/9/6 21:18
// @Desc   :
//
//                   _ooOoo_
//                  o8888888o
//                  88" . "88
//                  (| -_- |)
//                  O\  =  /O
//               ____/`---'\____
//             .'  \\|     |//  `.
//            /  \\|||  :  |||//  \
//           /  _||||| -:- |||||-  \
//           |   | \\\  -  /// |   |
//           | \_|  ''\---/''  |   |
//           \  .-\__  `-`  ___/-. /
//         ___`. .'  /--.--\  `. . __
//      ."" '<  `.___\_<|>_/___.'  >'"".
//     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//     \  \ `-.   \_ __\ /__ _/   .-` /  /
// =====`-.____`-.___\_____/___.-`____.-'=====
//                   `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//           佛祖保佑       永无BUG
//
package nacos

import (
	"distributedTransaction/utils"
	"encoding/json"
	"fmt"
	"github.com/nacos-group/nacos-sdk-go/vo"
	"time"
)

func PublishConfig(dataId, group, content string) (bool, error) {
	configClient, err := getConfigClient()
	if err != nil {
		fmt.Println("getConfigClient error, err = ", err.Error())
		return false, err
	}
	ok, err := configClient.PublishConfig(vo.ConfigParam{
		DataId:  dataId,
		Group:   group,
		Content: content,
	})
	if err != nil {
		fmt.Println("configClient.PublishConfig error, err = ", err.Error())
		return false, err
	}
	return ok, nil
}

func DeleteConfig(dataId, group string) (bool, error) {
	configClient, err := getConfigClient()
	if err != nil {
		fmt.Println("getConfigClient error, err = ", err.Error())
		return false, err
	}
	ok, err := configClient.DeleteConfig(vo.ConfigParam{
		DataId: dataId,
		Group:  group,
	})
	if err != nil {
		fmt.Println("configClient.DeleteConfig error, err = ", err.Error())
		return false, err
	}
	return ok, nil
}

func GetConfig(dataId, group string) (string, error) {
	configClient, err := getConfigClient()
	if err != nil {
		fmt.Println("getConfigClient error, err = ", err.Error())
		return "", err
	}
	content, err := configClient.GetConfig(vo.ConfigParam{
		DataId: dataId,
		Group:  group,
	})
	if err != nil {
		fmt.Println("configClient.GetConfig error, err = ", err.Error())
		return "", err
	}
	return content, nil
}

func listenConfig(dataId, group string, callback func(namespace, group, dataId, data string)) error {
	configClient, err := getConfigClient()
	if err != nil {
		fmt.Println("getConfigClient error, err = ", err.Error())
		return err
	}
	return configClient.ListenConfig(vo.ConfigParam{
		DataId:   dataId,
		Group:    group,
		OnChange: callback,
	})
}

func CancelListenConfig(dataId, group string) error {
	configClient, err := getConfigClient()
	if err != nil {
		fmt.Println("getConfigClient error, err = ", err.Error())
		return err
	}
	return configClient.CancelListenConfig(vo.ConfigParam{
		DataId: dataId,
		Group:  group,
	})
}

func ListenConfig(dataId, group string, config **utils.GlobalConfig) error {
	return listenConfig(dataId, group, func(namespace, group, dataId, data string) {
		// 指针赋值好像是线程安全的，因为指针是8位64bit嘛，一条指令就搞定了
		// 这里好像有个专有名词叫COW Copy-On-Write
		tmp := &utils.GlobalConfig{}
		err := json.Unmarshal(([]byte)(data), tmp)
		if err != nil {
			panic(err)
		}
		*config = tmp
	})
}

func ListenServerConfig(dataid, group string, config **utils.GlobalConfig) {
	err := ListenConfig(dataid, group, config)
	if err != nil {
		panic(fmt.Sprintf("nacos.ListenConfig error, err = %s", err.Error()))
	}
	time.Sleep(time.Millisecond * 100)
}
